결측지(Missing value)는 누락된 값, 비어 있는 값을 의미함.
결측치가 있으면 함수가 적용되지 않거나 분석 결과가 왜곡되는 문제
발생
NA (Not Available) : R에서 결측치를 처리하는 Logical
valueNaN (Not a Number) : NA와 비슷하게 생겼으나, 이는
계산이 불가능한 경우를 나타내는 numeric value (예: 분모를 0으로 나누는
경우)NA와 ’NA’는 다름 : ’NA’는 ’NA’라는 character
value임is.na(): vector object의 원소에 대해 결측치이면 TRUE,
결측치가 아니면 FALSE를 반환summary(): vector object의 원소 중 결측치가 있는 경우
7번째 원소로 결측치의 개수 카운팅y <- c(1:3, NA)
# 결측치 확인
is.na(y)
is.na("NA")
# 결측치 개수 카운팅
sum(is.na(y))
summary(y)na.rm=TRUE 옵션을 지원하지 않는 함수 존재 \(\rightarrow\) 함수 help문에서 결측치 제거
옵션 확인 필요. na.rm을 지원하지 않을 경우, filter()로
결측치 제거 후 함수 적용
filter(): 특정 행 추출%>%: pipe operator, chain operator라고 함. %>%
앞에 있는 출력 결과를 뒤에 있는 함수에게 보내주는 역할 (ctrl+shift+M
입력)na.omit(): 데이터에서 하나라도 결측치가 있는 경우, 해당
row를 제거한 뒤, 결측치가 없는 row만 반환complete.cases(): 각 row에서 결측값이 없는 경우 TRUE,
하나라도 결측치가 있는 경우 FALSE 반환weight <- c(65.4, 55, 380, 72.2, 51, NA)
height <- c(170, 155, NA, 173, 161, 166)
gender <- c(1, 2, 1, 1, 2, 2)
gender <- factor(gender, labels=c("M", "F"))
dxdate <- c("2040/09/01", "2040/09/01", "2040/09/05", "2040/09/14", "2040/10/11", "2040/11/11")
patient <- data.frame(weight, height, gender, dxdate)
patient
str(patient)
# 방법 1
library(dplyr) # ctrl + shift + M
patient %>% filter(!is.na(weight) & !is.na(height))
# 방법 2
na.omit(patient) # 결측치 있는 행 모두 제거
# 방법 3
complete.cases(patient) # 결측치 없는 행 TRUE 반환
patient[complete.cases(patient), ] # na.omit(patient)와 동일한 결과 데이터가 크고 결측치가 얼마 없는 경우에는 결측치를 제거하고 분석해도
크게 문제 없음.
그러나 데이터가 작고 결측치가 많은 경우, 결측치를 제거하면 많은 정보가
손실되어 분석 결과가 왜곡되는 문제 발생.
따라서 결측치 제거 대신 다른 값을 채워 넣는 방법을 ’결측치
대체법(Imputation)’이라 함.
# 결측치 확인
table(is.na(patient$weight))##
## FALSE TRUE
## 5 1
# 결측치 제외한 몸무게 평균 산출
mean(patient$weight, na.rm = TRUE)## [1] 124.72
# 몸무게가 NA면 평균값인 125로 대체
patient$weight1 <- ifelse(is.na(patient$weight), 125, patient$weight)
# 결측치 확인
table(is.na(patient$weight1))##
## FALSE
## 6
sum(), mean()과 같은 함수에서도 vector
object의 원소 중 결측치가 있는 경우 결과가 NA가 됨sum(), mean()과 같은 함수의 경우, 함수
내부에 결측치를 처리할 수 있는 옵션이 존재
na.rm=FALSE(default) : NA를 remove하라는 의미help(sum) 또는 ?sum을 통해 help문에서 확인
가능summarise()를 이용해 요약 통계량 산출 가능.
na.rm=FALSE(default) : NA를 remove하라는 의미8 + 2 + NA
8 - 2 + NA
8 * 2 * NA
NA / 2
NA * NA
NA <= 1df <- data.frame(sex = c("M","F","F",NA,"M"),
grade = c(5,4,3,2,NA))
df
mean(df$grade, na.rm = T) # 결측치 제외하고 평균 산출
sum(df$grade, na.rm=T) # 결측치 제외하고 합계 산출
library(dplyr)
df %>% summarise( max_grade = max(grade, na.rm=TRUE),
mean_grade = mean(grade, na.rm=TRUE),
sum_grade = sum(grade, na.rm=TRUE))age <- c(58, 78, 44, 88, 999, 13, 26, 999) # 999를 결측치를 사용한 경우
age[age == 999] <- NA # 999 부분을 NA로 치환
summary(age)
sum(age) # 결측치 포함하여 합계 계산
sum(age, na.rm=TRUE) # 결측치 제외하여 합계 계산apply() 함수에서 mean(), sum() 등을 적용할 때,
na.rm=T를 반영하고 싶은 경우, FUN 옵션 뒤에 na.rm=T 인자를 추가apply(patient[, 1:2], 2, mean, na.rm=T)
apply(patient[, 1:2], 1, sum, na.rm=T)정상 범주에서 크게 벗어난 값을 이상치(Outlier)라고 한다.
데이터 수집 과정에서 오류가 발생할 수 있음.
이상치가 포함되어 있으면 분석 결과가 왜곡되므로 이상치를 제거하는 작업이
필요함.
# sex: 남1, 여2; score: 1~5점;
outlier <- data.frame(sex = c(1, 2, 1, 3, 2, 1),
score = c(5, 4, 3, 4, 2, 6))
outlier## sex score
## 1 1 5
## 2 2 4
## 3 1 3
## 4 3 4
## 5 2 2
## 6 1 6
# 1. 이상치 확인
table(outlier$sex)##
## 1 2 3
## 3 2 1
table(outlier$score)##
## 2 3 4 5 6
## 1 1 2 1 1
# 2. 결측치 처리
outlier$sex <- ifelse(outlier$sex == 3, NA, outlier$sex)
outlier$score <- ifelse(outlier$score > 5, NA, outlier$score)
outlier## sex score
## 1 1 5
## 2 2 4
## 3 1 3
## 4 NA 4
## 5 2 2
## 6 1 NA
# 3. 결측치 제거 또는 대체
# 코드 생략-------# mpg 데이터(자동차 234종의 연비 관련 정보) 불러오기
# drv: 구동 방식(f = 전륜구동, r = 후륜구동, 4 = 사륜구동)
mpg <- data.frame(ggplot2::mpg)
# 1. boxplot 그리기
boxplot(mpg$hwy)
# 2. 통계치 확인
# : 아래쪽 극단치 경계, 1사분위수, 중앙값, 3사분위수, 위쪽 극단치 경계(출력결과: 위에서 아래순)
boxplot(mpg$hwy)$stats## [,1]
## [1,] 12
## [2,] 18
## [3,] 24
## [4,] 27
## [5,] 37
# 3. 결측치 처리
mpg$hwy <- ifelse(mpg$hwy < 12 | mpg$hwy > 37, NA, mpg$hwy)
# 4. 결측치 확인
table(is.na(mpg$hwy))##
## FALSE TRUE
## 231 3
# 5. 간단한 분석
mpg %>% group_by(drv) %>%
summarise(mean_hwy = mean(hwy, na.rm=T))## # A tibble: 3 x 2
## drv mean_hwy
## <chr> <dbl>
## 1 4 19.2
## 2 f 27.7
## 3 r 21
| 구분 | 자료형 확인 | 자료형 변환 |
|---|---|---|
| numeric | is.numeric() | as.numeric() |
| character | is.character() | as.character() |
| logical | is.logical() | as.logical() |
| vector | is.vector() | as.vector() |
| factor | is.factor() | as.factor() |
| date |
|
as.date() |
| matrix | is.matrix() | as.matrix() |
| data frame | is.data.frame() | as.data.frame() |
Date라는 자료구조를 가지고
있음as.Date(): character 또는 factor형 날짜값을 date로
변환difftime(): 첫 번째 인자의 날짜 빼기 두 번째 인자의
날짜의 차이를 units 단위로 환산difftime()의 units 지정가능한 값: “auto”,
“secs”, “mins”, “hours”, “days”, “weeks”str(patient)
patient$dxdate <- as.Date(patient$dxdate, format="%Y/%m/%d") # 진단일을 날짜형으로 변환
class(patient$dxdate)
str(patient)
x <- patient$dxdate[5] - patient$dxdate[1]
x
mode(x)
difftime(patient$dxdate[5], patient$dxdate[1], units="days")
difftime(patient$dxdate[5], patient$dxdate[1], units="weeks")"%Y": 4자리 연도"%m": 2자리 월"%d": 2자리 일as.Date()에서 format 옵션에 character형태(Y,m,d)로 값
지정strptime(): 시간 처리 함수month.name: 월 이름 목록month.abb: 월 이름 약어 목록as.Date("2023/03/28", format="%Y/%m/%d")
as.Date("12/10/2019", format = "%m/%d/%Y" )
as.Date("01012023", format="%m%d%Y")
as.Date("01012023", format="%Y")
month.name # 월 이름 목록
month.abb # 월 이름 약어 목록
now<-strptime("2023-03-28 13:45:00","%Y-%m-%d %H:%M:%S")
now$year # 연도. 1900년을 0으로 표준화한 값. 2023-1900
now$mon # 월
now$mday # 일
now$hour # 시간
now$min # 분
now$sec # 초
now$wday # 요일(일요일 0; 월요일 1; 화요일 2; ...)Sys.Date(): 현재 날짜를 YYYY-MM-DD의 형태로 반환Sys.time(): 현재 날짜와 시간까지 YYYY-MM-DD hh:mm:ss
timezone의 형태로 반환Sys.Date()
Sys.time()now(): Sys.time()과 동일year(), month(), day(): 연,
월, 일 추출wday(): 요일 factor 추출 (Sunday가 reference)years(), months(), hours(),
minutes(), seconds(): ()안의 수 입력하여
증감연산 가능# install.packages("lubridate")
library(lubridate)
date <- now()
date
year(date)
month(date)
day(date)
wday(date,label=T)
# 2040년 1월 1일부터 5일간의 날짜 데이터 생성
day1 <- as.Date("2040/01/01", "%Y/%m/%d")
day2 <- as.Date("2040/01/05", "%Y/%m/%d")
newdate <- seq(day1, day2, 1)
newdate
newdate + 365 # 1년 뒤 날짜로 변경 (윤달이 있는 경우 오류 발생 가능)
newdate + years(1) # 1년 뒤 날짜로 변경getwd(): 현재 작업 디렉토리 경로 반환setwd("path"): 원하는 디렉토리 경로 지정getwd() # 현재 경로 확인 (Check the current path)
mypath <- getwd() # 현재 경로 저장 (Save the current path)
# setwd("C:/Users/User/Desktop") # 바탕화면으로 경로 변경하기1 (change the path to desktop 1)
# setwd("C:\\Users\\User\\Desktop") # 바탕화면으로 경로 변경하기2 (change the path to desktop 2)
setwd(mypath) # 저장해둔 기존 경로로 변경 (Change to the saved path)paste0()을 이용하여 데이터 경로를 잡아보자.paste0("a", "bc")
paste0(1:3, c("a","b","c"))
# 작업경로 저장(Save working directory)
#path <- "C:/Users/User/Desktop/data"
path <- paste0(mypath,"/data")
pathread.csv() 이용해서 불러오기read.csv()의 디폴트 옵션은 header=T,
sep=","임. 변수명이 없는 경우, header=F
파라미터 지정write.csv()의 디폴트 옵션은
row.names=T이므로, csv파일의 경우
row.names=F는 따로 기재해주는 것을 권장read.csv(file, # 파일명 (경로 직접 지정 가능)
header=T, # 첫줄이 변수명인 경우 TRUE
sep=",", # 열구분자. 디폴트는 콤마 "," , 탭이면 "\t"로 변경
as.is=FALSE # string을 factor로 인식할 것인지. FALSE이면 문자변수를 factor로 변환.
na.strings="NA" # NA를 결측으로 인지
nrows =-1 # 2줄만 불러오고 싶을 때 nrows=2 입력. 음수로 설정할 경우 명령어 무시
skip =0 # 세 번째 줄부터 불러오고 싶으면 skip=2 입력
)
write.csv(object, # object (vector, matrix, dataframe 가능)
file, # 저장경로 및 파일명
quote=T, # TRUE인 경우 문자형 자료에 "" 붙여 저장, FALSE인 경우 "" 생략되어 저장
sep=" ", # 열구분자. 디폴트는 공백.
row.names=T, # 행이름 저장
col.names=T # 열이름 저장
)read.csv(paste0(path, "/humidity.txt"))
read.csv(paste0(path, "/humidity.txt"), na.strings=c(".", "NA"))
read.csv(paste0(path, "/temperature.txt"), sep=" ")
df1 <- read.csv(paste0(path,"/csv_exam_str.csv"))
str(df1)
df2 <- read.csv(paste0(path,"/csv_exam_str.csv"),as.is = FALSE)
str(df2)
df3 <- read.csv(paste0(path,"/csv_exam_noVar.csv"),header=F) # 첫 행부터 데이터 시작
head(df3)
str(df3)outpath <- paste0(path, "/output")
write.csv(df1, paste0(outpath, "/exam.csv"), row.names=F)
x <- c("남","여","남","남")
y <- c(20,21,22,23)
z <- data.frame(x,y)
z
write.csv(z, file = paste0(outpath,"/new_file.csv" ))
# 한글 깨짐 방지: fileEncoding = "UTF-8"
# 문자열에 따옴표 제거: quote=FALSE
write.csv(z, file = paste0(outpath,"/new_file1.csv" ),fileEncoding = "UTF-8", row.names=F)
write.csv(z, file = paste0(outpath,"/new_file2.csv" ),fileEncoding = "UTF-8", row.names=F, quote=FALSE)read_excel은 엑셀 파일을 데이터 프레임으로 만드는
기능이다.read.csv()로 읽어들이는 것이
확실함col_names = F 파라미터 설정readxl 패키지의 read_excel()로 엑셀파일에
바로 접근하여 데이터 호출 가능
read_excel( path, # 엑셀 파일 경로(항상 앞뒤에 따옴표)
sheet = NULL, # 특정 Sheet 불러올 때 사용
col_names = TRUE, # 열 이름 지정
na = "", # 빈 셀을 NA로 인식
skip = 0 # 몇 행을 건너뛰어서 불러올 것인지
)# install.packages(c("readxl", "writexl"))
library(readxl)
temp <- read_excel(paste0(path, "/temperature.xlsx"))
humid <- read_excel(paste0(path, "/temperature.xlsx"), sheet = 2) # 시트 순서를 이용한 호출
humid <- read_excel(paste0(path, "/temperature.xlsx"), sheet = "humidity") # 시트 이름을 이용한 호출
df1 <- read_excel(paste0(path,"/csv_exam_noVar.xlsx"))
head(df1)
str(df1)
df2 <- read_excel(paste0(path,"/csv_exam_noVar.xlsx"),col_names=F) # 첫 번째 행이 변수명이 아닐 때
head(df2)
str(df2)
library(writexl)
write_xlsx(temp, paste0(outpath, "/temperature2.xlsx"))THE END